package usbipclientsrv

import (
	log "github.com/sirupsen/logrus"
	"sync"
	"usbipproxy/domain/service"
)

type UsbipServerMgrServiceImpl struct {
	rwLock    sync.RWMutex
	mgr       map[string]UsbipClientServerService
	clientCmd service.UsbIpClientCmdService
}

func (u *UsbipServerMgrServiceImpl) Stop() {
	u.rwLock.Lock()
	defer u.rwLock.Unlock()
	for busId, srv := range u.mgr {
		//u.clientCmd.DetachByBusId(busId)
		srv.Stop()
		log.Infof("Stopped usbip server for bus %s", busId)
	}

}

func (u *UsbipServerMgrServiceImpl) RemoveBySessionId(busId, sessId string) error {
	u.rwLock.RLock()
	defer u.rwLock.RUnlock()
	service := u.mgr[busId]
	if service != nil && service.GetBusId() == busId {
		service.RecvHeartbeat(busId, sessId)
	} else {
		log.Infof("UsbipServerMgrServiceImpl RecvMsg can not find busId %v sessId：%v", busId, sessId)
	}

	return nil
}

func (u *UsbipServerMgrServiceImpl) RecvHeartbeat(busId, sessId string) error {
	u.rwLock.RLock()
	defer u.rwLock.RUnlock()
	service := u.mgr[busId]
	if service != nil {
		service.RecvHeartbeat(busId, sessId)
	} else {
		log.Infof("UsbipServerMgrServiceImpl RecvMsg can not find busId %v ", busId)
	}

	return nil
}

func (u *UsbipServerMgrServiceImpl) Remove(busId string) error {
	u.rwLock.Lock()
	defer u.rwLock.Unlock()
	log.Infof("UsbipServerMgrServiceImpl want remove busId:%v", busId)
	service := u.mgr[busId]
	if service != nil {
		//u.clientCmd.DetachByBusId(busId)
		service.Stop()
	} else {
		log.Infof("UsbipServerMgrServiceImpl Remove can not find busId %v ", busId)
	}
	delete(u.mgr, busId)

	return nil
}

func (u *UsbipServerMgrServiceImpl) Add(busId string, service UsbipClientServerService) error {
	u.rwLock.Lock()
	defer u.rwLock.Unlock()
	u.mgr[busId] = service
	log.Infof("UsbipServerMgrServiceImpl add busId:%v service：%p", busId, service)
	return nil
}

func (u *UsbipServerMgrServiceImpl) DeleteByNotifyConnId(notifyConnId int64) error {
	u.rwLock.Lock()
	defer u.rwLock.Unlock()

	for busId, service := range u.mgr {
		if service == nil {
			continue
		}
		if service.GetNotifyConnId() == notifyConnId {
			log.Infof("UsbipServerMgrServiceImpl delete notifyConnId:%v busId:%v", notifyConnId, busId)
			//u.clientCmd.DetachByBusId(busId)
			service.Stop()
			delete(u.mgr, busId)
		}
	}

	return nil
}

func (u *UsbipServerMgrServiceImpl) RecvAttachData(busId, sessId string, bytes []byte) error {
	u.rwLock.RLock()
	defer u.rwLock.RUnlock()
	service := u.mgr[busId]
	if service != nil {
		service.RecvAttachData(sessId, bytes)
	} else {
		log.Infof("UsbipServerMgrServiceImpl RecvMsg can not find busId %v ", busId)
	}

	return nil
}

func NewUsbipServerMgrServiceImpl(clientCmd service.UsbIpClientCmdService) UsbipServerMgrService {
	return &UsbipServerMgrServiceImpl{
		clientCmd: clientCmd,
		mgr:       make(map[string]UsbipClientServerService),
	}
}
